#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/loadavg.h>
#include <unistd.h>
#include <time.h>

#define err(msg) do { perror(msg); exit(EXIT_FAILURE); } while(0)

int main(int argc, char *argv[])
{
	struct sockaddr_un address;
	fd_set set;
	int socket_fd, connection_fd;
	socklen_t address_length;
	struct timeval interval;
	pid_t pid;
	uid_t uid;
	gid_t gid;
	char data[1024];
	double load[3];
	time_t start;
	pid = getpid();
	uid = getuid();
	gid = getgid();
	start = time(NULL);
	address_length = sizeof(struct sockaddr_in);
	FD_ZERO(&set);
	unlink("./socket");
	if((socket_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) err("server8:socket");
	address.sun_family = AF_UNIX;
	strcpy(address.sun_path,"./socket");
 	if(bind(socket_fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) err("server8:bind");
	if(listen(socket_fd, 5) != 0) err("server8:listen");
	for(;;)
	{
		FD_CLR(socket_fd, &set);
		FD_SET(socket_fd, &set);	
		interval.tv_sec = (time_t)1;
		interval.tv_usec = (time_t)0;
		if(select(socket_fd+1, &set, NULL, NULL, &interval) == -1) err("server8:select");
		if (FD_ISSET(socket_fd, &set))
		{
			if((connection_fd = accept(socket_fd, (struct sockaddr *) &address, &address_length)) < 0) err("server8:accept");
			if(getloadavg(load,3) == -1) err("server8:getloadavg");
			sprintf(data,"pid:%ld\nuid:%ld\ngid:%ld\nseconds:%ld\n1:%f\t5:%f\t15:%f\n",pid,uid,gid,time(NULL)-start,load[0],load[1],load[2]);
			write(connection_fd, data, strlen(data));
			close(connection_fd);
		}
	}
	return 0;
}
